#include <page.h>
#include <assert.h>

// this is the constructor the arg tells the page how many bytes it
// is allowed to store

Page:: Page (int maxSizeInBytes)
{
	m_iPageSize = maxSizeInBytes;
	m_iBytesInPage = sizeof(int);
	m_iCurrRecPtr  = m_iBytesInPage;
}

Page::~Page ()
{
	m_iPageSize = 0;
	m_iBytesInPage = 0;
	m_iCurrRecPtr = 0;
}


// this takes a page and writes its binary representation to bits
int Page::ToBinary (char *_bits)
{
	char * temp;
	assert(_bits);
	list<Record> :: const_iterator i;
	int memSpace = sizeof(int);
	int total = 0;
	
	for(i=m_lRecordList.begin();i!= m_lRecordList.end(); i++)
	{
		Record rp;
		rp = *i;
		temp = _bits + memSpace;
		total = rp.ToBinary(temp);
		memSpace = memSpace + total;
	}
	memmove(_bits, &memSpace,sizeof(memSpace));		
	return(memSpace);
}

// this takes a binary representation of a page and gets the
// records from it
int Page::FromBinary (char *_bits)
{
	char * temp;
	int countMem = 0;
	int memoryInBin = 0;
	int x = 0;
	memmove(&memoryInBin, _bits, sizeof(memoryInBin));
	
	countMem = sizeof(memoryInBin);
	while(countMem < memoryInBin)
	{
		temp = _bits + countMem;
		Record rec;
		x = rec.FromBinary(temp);
		Record r;
		r.Consume(rec);
		countMem = countMem + x;
		m_lRecordList.push_back(r);
	}
	m_iBytesInPage = countMem;
	return(m_iBytesInPage);
}

// the deletes the first record from a page and returns it returns
// a zero if there were no records on the page
int Page::GetFirst (Record &_firstOne)
{
/*	cout<<"bytes = "<<m_iBytesInPage<<endl;
	cout<<"size ="<< m_lRecordList.size()<<endl;*/
	if(m_lRecordList.size() <= 0)
	{
		return 0;
	}
	else
	{
		_firstOne.Consume(m_lRecordList.front());
		m_lRecordList.pop_front();
		m_iBytesInPage = m_iBytesInPage - _firstOne.HowManyBytes();
	}
	return 1;
}

// this appends the record to the end of a page.  The return value
// is a one on success and a zero if there is no more space.
// Note that the record is consumed so it will have no value after

int Page:: Append (Record &_addMe) 
{
	int retVal = 0;
	int recBytes = _addMe.HowManyBytes();
	int testBytes = recBytes + m_iBytesInPage;
	if(testBytes > m_iPageSize)
	{
		retVal = 0;
	}
	else
	{
		retVal = 1;
		Record rec;
		rec.Consume(_addMe);
		m_lRecordList.push_back(rec);
		m_iBytesInPage = m_iBytesInPage + recBytes;
	}
	return (retVal);
}

// empty out the page so that it contains no records
//?does this mean clear or write to binary??????
void Page:: EmptyItOut ()
{
	list<Record> :: const_iterator i;
	for(i=m_lRecordList.begin();i!= m_lRecordList.end(); i++)
	{
		Record rp;
		rp = *i;
		rp.SetFree();
	}
	m_lRecordList.clear();
	m_iBytesInPage = sizeof(int);
	m_iCurrRecPtr  = sizeof(int);
}

int Page:: GetRecordCount()
{
	return m_lRecordList.size();
}

/*
void Page::Test(Schema &mySchema, FILE * fp)
{
	Record r1 (mySchema);
	Record r2 (mySchema);
	Record r3 (mySchema);
 
	r1.SuckNextRecord(mySchema,fp);
	r2.SuckNextRecord(mySchema,fp);
	r3.SuckNextRecord(mySchema,fp);

	m_lRecordList.push_back(r1);
	m_lRecordList.push_back(r2);
	m_lRecordList.push_back(r3);


	list<Record> :: iterator i;
	Record rp;

	for(i=m_lRecordList.begin();i!= m_lRecordList.end(); i++)
	{
		rp = *i;
		rp.Print(mySchema);  
	}
}
*/
